import axios from "axios";
import _utils from "@/public/utils";
import apienv from "./env";
import constant from "@/public/constant";
import api from "@/api";
import router from "../router";
import store from "../store";
import sendMain from "lesso-common/event/ipcRenderer";
import { MessageBox } from "element-ui";
import _debounce from "lodash/debounce";

const env = apienv[constant.appenv];
// axios 默认设置
axios.defaults.retry = 5;
axios.defaults.retryDelay = 1000;
// axios.defaults.timeout = 30000 // 超时
let pending = [];

let removePending = (ever) => {
  for (let p in pending) {
    if (pending[p].u === ever.url + "&" + ever.method) {
      //当当前请求在数组中存在时执行函数体
      pending[p].f(); //执行取消操作
      pending.splice(p, 1); //把这条记录从数组中移除
    }
  }
};
// axios 拦截器
axios.interceptors.response.use(
  (response) => {
    //取消请求
    removePending(response.config);
    //登录失效的时候重定向为登录页面
    if (response.data.code == -11) {
      userLogout();
      return response;
    } else if (
      response.data.code == 21 ||
      response.data.code == -21 ||
      response.data.code == 22
    ) {
      if (response.data.code == 21 || response.data.code == 22) {
        if (constant.userAgent == "web") {
          constant.token = response.data.data;
          store.commit("changeUserToken", response.data.data);
        } else {
          constant.token = response.data.data;
          store.commit("changeUserToken", response.data.data);
          sendMain("changeToken", response.data.data);
        }
      }
      // 判断是否配置了重试
      var config = response.config;
      if (!config || !config.retry) return response;
      // 设置重置次数，默认为0
      config.__retryCount = config.__retryCount || 0;
      // 判断是否超过了重试次数
      if (config.__retryCount >= config.retry) {
        userLogout();
        return response;
      }
      config.__retryCount += 1;
      // 延时
      var backoff = new Promise(function(resolve) {
        setTimeout(function() {
          resolve();
        }, config.retryDelay || 1);
      });

      //重新发起axios请求
      return backoff.then(function() {
        var jwt = constant.token;
        if (jwt) {
          config.headers.authorization = constant.token;
        }
        return axios(config);
      });
    } else if (response.data.code == -31) {
      noAuthority();
      return response;
    } else {
      return response;
    }
  },
  (error) => {
    if (error.response) {
      // 有返回的报错
      switch (error.response.status) {
        case 400: // 服务器报错
          if (typeof error.response.data !== "object") {
            error.response.data = {};
          }
          error.response.data.message = "无效的请求！";
          break;
        case 404: // 接口不存在
          if (typeof error.response.data !== "object") {
            error.response.data = {};
          }
          error.response.data.message = "接口不存在";
          break;
        default:
          // 服务器其他异常
          if (typeof error.response.data !== "object") {
            error.response.data = {};
          }
          let info = error.response.data.info
            ? error.response.data.info
            : "服务器异常，请求失败！";
          error.response.data.message = info;
          break;
      }
    } else {
      // 没有返回报错
      error.response = {};
      error.response.data = {};
      // 超时或者其他异常
      error.response.data.message = "服务器异常！";
    }
    return Promise.reject(error.response);
  }
);

// 用户退出登录
const userLogout = _debounce(() => {
  // /**
  //  * TODO: 退出登录方法
  //  */
  MessageBox.alert("登录已过期，请重新登录", {
    showClose: false,
    confirmButtonText: "确定",
    customClass: "alertFailure",
    callback: () => {
      // 直接退出不清空 redis
      store.commit("loginOut");
      constant.token = "";
      if (constant.userAgent == "web") {
        router.push({
          name: "login",
        });
      } else {
        sendMain("openLoginWin");
      }
    },
  });
}, 300);
// 无权限访问
const noAuthority = _debounce(() => {
  MessageBox.alert("无权限访问", {
    showClose: false,
    confirmButtonText: "确定",
    customClass: "alertFailure",
  });
}, 300);
// 构造请求头新的用户 token ---20200519
const getAuthCodeToken = () => {
  let data = {
    ...constant.authCode,
    deviceId: window.fingerprint,
    uid: constant.userId,
  };
  let result = window.btoa(JSON.stringify(data));
  return result;
};
const req = function(
  baseUrl,
  method,
  url,
  params,
  reference,
  isbody,
  file,
  blob
) {
  let config = {
    method: method,
    url: `${env[baseUrl]}${url}`,
    // timeout: 20000,
    headers: {
      systemId: 47,
      device: "PC",
      lang: "zh",
    },
  };
  if (constant.authCode) {
    config.headers.token = getAuthCodeToken();
  }

  if (constant.token && constant.userId) {
    config.headers["authorization"] = constant.token;
    config.headers["uid"] = constant.userId;
    config.headers["userTypeId"] = constant.accountType;
    config.headers.token && (config.headers.token = getAuthCodeToken());
  }
  // 设备标识
  if (window.fingerprint) {
    config.headers.deviceId = window.fingerprint;
  }
  if (blob) {
    config.responseType = "arraybuffer";
  }
  method = method.toUpperCase();
  if (isbody) {
    if (file) config.params = params;
    else config.data = params;
  } else if (method == "GET" || method == "DELETE" || method == "PUT") {
    if (!reference) {
      config.url += `/?data=${encodeURIComponent(JSON.stringify(params))}`;
    } else {
      config.params = params;
      config.url += `?ts=${Date.parse(new Date())}`;
    }
  } else {
    config.data = params;
    config.url += `?${Date.parse(new Date())}`;
  }
  return axios(config);
};

const fileUpload = function(data, timeout) {
  let config = {
    method: "POST",
    url: `${env.srm}upload/file`,
    timeout: 20000,
    headers: {
      "Content-Type": "multipart/form-data",
      // 'authorization': constant.userData.token,
      // 'uid': constant.userData.user.id,
      systemId: constant.systemId,
      device: "PC",
      sys: "SIGN",
    },
    data: data,
  };
  if (constant.token) {
    config.headers["authorization"] = constant.token;
    config.headers["uid"] = constant.userId;
  }
  if (timeout) {
    config.timeout = timeout;
  }
  return axios(config);
};

const req3 = ({
  baseUrl,
  method,
  url,
  params,
  timeout,
  isOriginalGET,
  isBlob,
  isLogin,
}) => {
  let userData = {};
  // 非登录接口加鉴权
  if (!isLogin) {
    userData = _utils.getSession("userData");
  }
  !params && (params = {});
  params.userName = constant.userName;
  params.userId = constant.userId;
  let config = {
    method: method,
    url: env[baseUrl] + url,
    timeout: 20000,
    headers: {
      systemId: constant.systemId,
      device: "PC",
    },
  };
  // 用来覆盖默认的超时时间
  if (timeout) {
    config.timeout = timeout;
  }
  if (constant.authCode) {
    config.headers.token = getAuthCodeToken();
  }
  // 判断是否有鉴权
  if (userData.user.id && userData.token) {
    config.headers.uid = userData.user.id;
    config.headers.authorization = userData.token;
    config.headers["userTypeId"] = userData.user.userTypeId;
    config.headers.token && (config.headers.token = getAuthCodeToken());
  }
  if (isBlob) {
    config.responseType = "arraybuffer";
  }
  method = method.toUpperCase();
  if (method == "GET") {
    if (isOriginalGET) {
      config.params = params;
    } else {
      config.url += `/${encodeURIComponent(JSON.stringify(params))}`;
    }
  } else {
    config.data = params;
  }
  // 在请求地址后面加时间戳
  if (config.params) {
    config.params.ts = `${new Date().getTime()}`;
  } else {
    config.params = {
      ts: `${new Date().getTime()}`,
    };
  }

  return axios(config);
};

export { req, req3, fileUpload };

// export default req;
